import { RedisServiceFactory } from "@midwayjs/redis";
import { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core";
import Config from "@/base/Config";
import { MathUtils } from "@/util/common/utils";

@Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true })
export class RedisCache {

    @Inject()
    redisServiceFactory: RedisServiceFactory;

    GetInstance(client: string) {
        const redis = this.redisServiceFactory.get(client);
        return redis
    }

    /**
     * redis新增
     * 
     * @param client redis
     * @param key 主键
     * @param value 键值
     * @param temporary 是否随机临时
     * @param seconds 时间
     */
    async set(client: string, key: string, value: string | number | any, temporary?: boolean, seconds?: number) {
        value = JSON.stringify(value);
        if (temporary) {
            if (!seconds) {
                await this.GetInstance(client).set(key, value, "EX", MathUtils.createRandomByNum(2, 4) * Config.READISBASE.redis.expire)
            } else {
                await this.GetInstance(client).set(key, value, "EX", seconds)
            }
        } else {
            if (!seconds) {
                await this.GetInstance(client).set(key, value)
            } else {
                await this.GetInstance(client).set(key, value, "EX", seconds)
            }
        }

    }

    /**
     * redis获取
     * 
     * @param client redis
     * @param key 主键
     * @returns 结果
     */
    async get(client: string, key: string): Promise<any[]> {
        let data = await this.GetInstance(client).get(key) as any;
        if (!data) {
            return []
        }
        data = JSON.parse(data) as any[];
        return data
    }

    /**
     * redis匹配
     * 
     * @param client redis
     * @param pattern 匹配字符
     * @returns 结果
     */
    async keys(client: string, pattern: string) {
        let data = await this.GetInstance(client).keys(pattern);
        if (!data) {
            return
        }
        return data
    }

    /**
     * redis删除
     * 
     * @param client redis
     * @param key 主键
     * @returns 结果
     */
    async del(client: string, keys: string[]) {
        try {
            for (const key in keys) {
                if (Object.prototype.hasOwnProperty.call(keys, key)) {
                    const k = keys[key];
                    await this.GetInstance(client).del(k);
                }
            }
            return true
        } catch (error) {
            return false
        }
    }

    /**
     * redis续期
     * 
     * @param client redis
     * @param key 主键
     * @param temporary 是否随机临时
     * @param seconds 时间
     */
    async expire(client: string, key: string, seconds: number, temporary?: boolean) {
        if (temporary) {
            await this.GetInstance(client).expire(key, MathUtils.createRandomByNum(2, 4) * Config.READISBASE.redis.expire)
        } else {
            await this.GetInstance(client).expire(key, seconds)
        }
    }

    /**
     * redis清空缓存
     * 
     * @param client redis
     * @returns 成功
     */
    async flushall(client: string) {
        this.GetInstance(client).flushall();
    }
}